package com.south.base.test.arithmetic;

import org.junit.Test;

import java.util.Arrays;

/**
 * 将一个给定字符串根据给定的行数，以从上往下、从左到右进行 Z 字形排列。
 *
 * @author Administrator
 * @date 2019/11/21 15:12
 */
public class Convert2Z {
    @Test
    public void convert() {
        System.out.println(convert("LEETCODEISHIRING", 3));
        System.out.println(convert2("A", 2));
        System.out.println(Arrays.deepToString(convertArray("LEETCODEISHIRING", 1)));
    }

    public String convert(String s, int numRows) {
        if (numRows <= 1) return s;
        int z = numRows * 2 - 2;
        StringBuilder[] c = new StringBuilder[numRows];
        for (int i = 0; i < numRows; i++) {
            c[i] = new StringBuilder();
        }
        for (int i = 0; i < s.length(); i++) {
            int mod = (i + 1) % z;
            mod = mod == 0 ? z : mod;
            if (mod >= numRows) {
                c[2 * numRows - mod - 1].append(s.charAt(i));
            } else {
                c[mod - 1].append(s.charAt(i));
            }
        }
        StringBuilder sb = new StringBuilder();
        for (StringBuilder stringBuilder : c) {
            sb.append(stringBuilder);
        }
        return sb.toString();
    }

    public String convert2(String s, int numRows) {
        char[][] c = convertArray(s, numRows);
        StringBuilder sb = new StringBuilder();
        for (char[] chars : c) {
            for (char c1 : chars) {
                if (c1 != '\u0000') {
                    sb.append(c1);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 组装Z形二维数组
     * @param s
     * @param numRows
     * @return
     */
    public char[][] convertArray(String s, int numRows) {
        if (numRows == 1) {
            char[][] c = new char[numRows][s.length()];
            for (int i = 0; i < c[0].length; i++) {
                c[0][i] = s.charAt(i);
            }
            return c;
        }
        int z = numRows * 2 - 2;
        char[][] c = new char[numRows][length(s.length(), z, numRows)];
        for (int i = 0; i < s.length(); i++) {
            int mod = (i + 1) % z;
            mod = mod == 0 ? z : mod;
            if (mod >= numRows) {
                c[2 * numRows - mod - 1][length2(i, z, numRows)] = s.charAt(i);
            } else {
                c[mod - 1][length2(i, z, numRows)] = s.charAt(i);
            }
        }
        return c;
    }

    private int length(int i, int z, int numRows) {
        int length = (i / z) * (numRows - 1);
        int mod = i % z;
        if (mod >= numRows) {
            length += mod - numRows + 1;
        } else if (mod != 0 && length != 0) {
            length += 1;
        }
        return length == 0 ? 1 : length;
    }

    private int length2(int i, int z, int numRows) {
        int length = (i / z) * (numRows - 1);
        int mod = i % z;
        if (mod >= numRows) {
            length += mod - numRows + 1;
        }
        return length;
    }
}
